package jp.ac.aiit.spg.web.wbs;

import java.util.*;

import javax.ejb.EJB;

import org.seasar.teeda.extension.annotation.convert.DateTimeConverter;
import org.seasar.teeda.extension.annotation.validator.Required;

import jp.ac.aiit.spg.common.SpgAssignStatus;
import jp.ac.aiit.spg.common.SpgConstant;
import jp.ac.aiit.spg.common.SpgRole;
import jp.ac.aiit.spg.entity.*;
import jp.ac.aiit.spg.service.SpgService;

public class UpdateTaskPage {

	@EJB
	private SpgService ss;

	private int taskId;

	private SpgTask task;

	@Required
	private String taskName;

	private String wbsNumber;

	@Required
	private int workingTime;

	private boolean startTimeSpecified;

	@DateTimeConverter(pattern = "yyyy/MM/dd HH")
	private Date startTimePlanned;

	@DateTimeConverter(pattern = "yyyy/MM/dd HH")
	private Date finishTimePlanned;

	private List<SpgMember> members;

	@Required
	private int spgmemberid;

	private List<SpgMemberItem> spgmemberidItems;

	@Required
	private int assignStatusid;

	private List<Map> assignStatusidItems;

	private int projectid;

	private boolean StartTimeSpecified;

	private List<SpgTask> parentTasks;

	@Required
	private int parentTaskid;

	private List<SpgTaskItem2> parentTaskidItems;

	private List<SpgTask> predecessorTasks;

	@Required
	private Integer[] predecessorTaskids;

	private List<SpgTaskItem2> predecessorTaskidsItems;

	private String currentAssignment;

	private String deliverableMemo;

	private String assignMemo;

	public String getCurrentAssignment() {
		return currentAssignment;
	}

	public void setCurrentAssignment(String currentAssignment) {
		this.currentAssignment = currentAssignment;
	}

	public int getProjectid() {
		return projectid;
	}

	public void setProjectid(int projectid) {
		this.projectid = projectid;
	}

	public SpgTask getTask() {
		return task;
	}

	public void setTask(SpgTask task) {
		this.task = task;
	}

	public int getTaskId() {
		return taskId;
	}

	public void setTaskId(int taskId) {
		this.taskId = taskId;
	}

	public String getTaskName() {
		return taskName;
	}

	public void setTaskName(String taskName) {
		this.taskName = taskName;
	}

	public List<SpgMember> getMembers() {
		return members;
	}

	public void setMembers(List<SpgMember> members) {
		this.members = members;
	}

	public List<SpgMemberItem> getSpgmemberidItems() {
		return spgmemberidItems;
	}

	public void setSpgmemberidItems(List<SpgMemberItem> spgmembermanyItems) {
		this.spgmemberidItems = spgmembermanyItems;
	}

	public int getSpgmemberid() {
		return spgmemberid;
	}

	public void setSpgmemberid(int spgmembermany) {
		this.spgmemberid = spgmembermany;
	}

	public Class initialize() {
		return null;
	}

	public Class prerender() {
		// タスクの取得
		task = ss.getTask(taskId);

		// タスクの属性を画面にセット
		taskName = task.getName();
		wbsNumber = task.getWbsNumber();
		workingTime = task.getWorkingTime();
		startTimeSpecified = task.isStartTimeSpecifiedByUser();
		startTimePlanned = task.getStartTimePlanned();
		finishTimePlanned = task.getFinishTimePlanned();
		deliverableMemo = task.getDeliverableMemo();
		assignMemo = task.getAssignMemo();

		// チームメンバーの名前をとってきて表示コンポーネントに詰める。
		// 現行の値もセットする。
		prepareMemberOptions();

		// 承認状態の選択肢を表示コンポーネントに詰める
		// 現行の値もセットする。
		prepareAssignOptions();

		// 親タスクとして指定できるタスクのリストをとってきて表示コンポーネントに詰める。
		// （ルートも追加する。）
		// 現行の値もセットする。
		prepareParentOptions();

		// 先行タスクとして指定できるタスクのリストをとってきて表示コンポーネントに詰める。
		//（ルートはなし。先行タスク無を明示的に指定もできるようにする）
		// 現行の値もセットする。
		preparePredecessorOptions();

		return null;
	}

	private void preparePredecessorOptions() {
		
		// プロジェクトの全タスクのリストを得る
		predecessorTaskidsItems = new ArrayList<SpgTaskItem2>();
		String[] sortOrder = { "wbsNumber" };
		predecessorTasks = ss.listAllProjectTask(projectid, sortOrder);
		
		// 先行タスク無しの明示指定オプションを選択肢に追加する
		SpgTaskItem2 unselectitem = new SpgTaskItem2();
		unselectitem.setValue(SpgConstant.NOT_A_TASK);
		unselectitem.setLabel("先行タスクなし");
		predecessorTaskidsItems.add(unselectitem);

		// タスクのリストを選択肢に追加する。
		// 自分自身は選択肢から除くこと！（ループ防止）
		for (SpgTask t : predecessorTasks) {
			if (  t.getId().intValue() != task.getId().intValue()  ) { 							
				SpgTaskItem2 item2 = new SpgTaskItem2();
				item2.setValue(t.getId());
				item2.setLabel(t.getWbsNumber() + " : " + t.getName());
				predecessorTaskidsItems.add(item2);
			}
		}

		// 現在タスクに割り当てられている先行タスクを初期表示時の選択値とする。
		Set<SpgTask> currentPreds = task.getPredecessors();
		predecessorTaskids = new Integer[currentPreds.size()];
		int n = 0;
		for (SpgTask t : currentPreds) {
			predecessorTaskids[n] = t.getId();
			n++;
		}
	}

	private String[] prepareParentOptions() {

		// プロジェクトの全タスクのリストを得る
		String[] sortOrder = { "wbsNumber" };
		parentTasks = ss.listAllProjectTask(projectid, sortOrder);
		
		// ルート・タスクを明示的にリストに追加する
		SpgTask rootTask = ss.getRootTask(projectid);
		parentTasks.add(0, rootTask);

		// 選択肢にタスクを追加する。
		// 自分自身は選択肢から除くこと！
		parentTaskidItems = new ArrayList<SpgTaskItem2>();
		for (SpgTask t : parentTasks) {
			if (  t.getId().intValue() != task.getId().intValue()  ) {
				SpgTaskItem2 item = new SpgTaskItem2();
				item.setValue(t.getId());
				item.setLabel(t.getWbsNumber() + " : " + t.getName());
				parentTaskidItems.add(item);
			}
		}

		// 現在タスクに割り当てられている親タスクを初期表示時の選択値とする。
		parentTaskid = task.getParent().getId();
		return sortOrder;
	}

	private void prepareAssignOptions() {
		currentAssignment = task.getAssignment().toString();

		// 承認状態の選択肢を表示コンポーネントに詰める
		assignStatusidItems = new ArrayList<Map>();
		Map map1 = new HashMap();
		map1.put("label", "変更なし");
		map1.put("value", new Integer(1));
		assignStatusidItems.add(map1);
		Map map2 = new HashMap();
		map2.put("label", SpgAssignStatus.CREATED.toString());
		map2.put("value", new Integer(2));
		assignStatusidItems.add(map2);
		Map map3 = new HashMap();
		map3.put("label", SpgAssignStatus.ASSIGNED.toString());
		map3.put("value", new Integer(3));
		assignStatusidItems.add(map3);

		// 承認状態のデフォルトの選択肢を設定。
		assignStatusid = 1;
	}

	private void prepareMemberOptions() {
		spgmemberidItems = new ArrayList<SpgMemberItem>();

		members = ss.listAllMember(projectid);
		for (SpgMember m : members) {
			if (m.getRole() != SpgRole.TEACHER) {
				SpgMemberItem item = new SpgMemberItem();
				item.setValue(m.getId());
				item.setLabel(m.getUser().getName() + " : "
						+ m.getUser().getDescription());
				spgmemberidItems.add(item);
			}
		}

		// 現在タスクに割り当てられているメンバーを初期表示時の選択値とする。
		spgmemberid = task.getMember().getId();
	}

	public Class doUpdate() {

		// タスク作成テンプレートを使って値をサービスにわたす。
		SpgTaskTemplete stt = new SpgTaskTemplete();

		// タスクの属性の設定
		stt.name = taskName;
		stt.workingTime = workingTime;
		stt.isStartTimeSpecifyedByUser = startTimeSpecified;
		stt.startTimePlanned = startTimePlanned;

		switch (assignStatusid) {
		case 2:
			stt.assignment = SpgAssignStatus.CREATED;
			break;
		case 3:
			stt.assignment = SpgAssignStatus.ASSIGNED;
			break;
		default:
			// 何もしない
			;
		}
		stt.deliverableMemo = deliverableMemo;
		stt.assignMemo = assignMemo;
		stt.projectId = projectid;
		stt.memberId = spgmemberid;
		stt.parentTaskId = parentTaskid;

		stt.PredecessorIds = new ArrayList<Integer>();
		if (predecessorTaskids.length != 0) {
			for (Integer i : predecessorTaskids) {
				stt.PredecessorIds.add(i);
			}
		}

		ss.updateTask(taskId, stt);

		return ConfirmTaskPage.class;
	}

	public String getWbsNumber() {
		return wbsNumber;
	}

	public void setWbsNumber(String wbsNumber) {
		this.wbsNumber = wbsNumber;
	}

	public int getWorkingTime() {
		return workingTime;
	}

	public void setWorkingTime(int workingTime) {
		this.workingTime = workingTime;
	}

	public Date getStartTimePlanned() {
		return startTimePlanned;
	}

	public void setStartTimePlanned(Date startTimePlanned) {
		this.startTimePlanned = startTimePlanned;
	}

	public int getAssignStatusid() {
		return assignStatusid;
	}

	public void setAssignStatusid(int assignStatusid) {
		this.assignStatusid = assignStatusid;
	}

	public List<Map> getAssignStatusidItems() {
		return assignStatusidItems;
	}

	public void setAssignStatusidItems(List<Map> assignStatusidItems) {
		this.assignStatusidItems = assignStatusidItems;
	}

	public int getParentTaskid() {
		return parentTaskid;
	}

	public void setParentTaskid(int parentTaskid) {
		this.parentTaskid = parentTaskid;
	}

	public List<SpgTaskItem2> getParentTaskidItems() {
		return parentTaskidItems;
	}

	public void setParentTaskidItems(List<SpgTaskItem2> parentTaskidItems) {
		this.parentTaskidItems = parentTaskidItems;
	}

	public List<SpgTask> getParentTasks() {
		return parentTasks;
	}

	public void setParentTasks(List<SpgTask> parentTasks) {
		this.parentTasks = parentTasks;
	}

	public Integer[] getPredecessorTaskids() {
		return predecessorTaskids;
	}

	public void setPredecessorTaskids(Integer[] predecessorTaskids) {
		this.predecessorTaskids = predecessorTaskids;
	}

	public List<SpgTaskItem2> getPredecessorTaskidsItems() {
		return predecessorTaskidsItems;
	}

	public void setPredecessorTaskidsItems(
			List<SpgTaskItem2> predecessorTaskidsItems) {
		this.predecessorTaskidsItems = predecessorTaskidsItems;
	}

	public List<SpgTask> getPredecessorTasks() {
		return predecessorTasks;
	}

	public void setPredecessorTasks(List<SpgTask> predecessorTasks) {
		this.predecessorTasks = predecessorTasks;
	}

	public boolean isStartTimeSpecified() {
		return startTimeSpecified;
	}

	public void setStartTimeSpecified(boolean startTimeSpecified) {
		this.startTimeSpecified = startTimeSpecified;
	}

	public Date getFinishTimePlanned() {
		return finishTimePlanned;
	}

	public void setFinishTimePlanned(Date finishTimePlanned) {
		this.finishTimePlanned = finishTimePlanned;
	}

	public String getAssignMemo() {
		return assignMemo;
	}

	public void setAssignMemo(String assignMemo) {
		this.assignMemo = assignMemo;
	}

	public String getDeliverableMemo() {
		return deliverableMemo;
	}

	public void setDeliverableMemo(String deliverableMemo) {
		this.deliverableMemo = deliverableMemo;
	}

}
